package cn.git.shiro.realm;

import cn.git.shiro.entity.Permissions;
import cn.git.shiro.entity.Role;
import cn.git.shiro.entity.User;
import cn.git.shiro.service.PermissionsService;
import cn.git.shiro.service.RoleService;
import cn.git.shiro.service.UserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @description: 自定义realm类
 * @program: bank-credit-sy
 * @author: lixuchun
 * @create: 2024-03-26
 */
@Component
public class CustomRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private PermissionsService permissionsService;

    /**
     * 授权权限方法
     * 注解使用如下：
     *  RequiresAuthorization 验证用户是否登录，等同于 subject.isAuthenticated()
     *  RequiresUser 验证用户是否被记忆，登录成功 subject.isAuthenticated()为true,被记忆 subject.isRemembered()为true
     *  RequiresGuest 作用是验证用户是否未登录，即未认证，即未登录，此时subject.isAuthenticated()为false,subject.isRemembered()为false,subject.getPrincipals()为null
     *  RequiresRoles 验证用户是否具有某个角色，如：@RequiresRoles("admin")
     *  RequiresPermissions 验证用户是否具有某个权限, 如：@RequiresPermissions("user:add")
     *
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 获取登录用户信息
        User user = null;
        if (principals != null) {
            user = (User) principals.getPrimaryPrincipal();
        }

        // 创建对象，用户封装角色和权限信息
        Role role = roleService.getRoleById(user.getRid());
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        // 存储角色信息,正常使用user.getRid()然后获取role表中的所有角色信息，
        authorizationInfo.addRole(role.getName());

        // 获取用户权限信息,正常一个用户有多个角色，一个角色对应多个权限，此处演示就都设置为一个角色，一个权限
        Permissions permissions = permissionsService.getPermissionsById(role.getPid());
        authorizationInfo.addStringPermission(permissions.getInfo());

        return authorizationInfo;
    }

    /**
     * 登录认证方法
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 1.获取用户身份信息，用户名称
        String username = token.getPrincipal().toString();

        // 2.根据用户名称查询用户信息
        User user = userService.getUserByName(username);

        // 3.封装用户信息,返回
        if (user != null) {
            AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                    user,
                    user.getPwd(),
                    ByteSource.Util.bytes("3313"),
                    CustomRealm.class.getName()
            );

            return authenticationInfo;
        }
        return null;
    }

}
